// {
//     "onMove" : {
//       "required uInt32 entityId" : 1,
//       "message Path": {
//         "required uInt32 x" : 1,
//         "required uInt32 y" : 2
//       },
//       "repeated Path path" : 2,
//       "required uInt32 speed" : 3
//     },
//     "onAttack" : {
//       "required uInt32 attacker" : 1,
//       "required uInt32 target" : 2
//     }
// }

var jsStruct=require('./jsStruct');
var tsStruct=require('./tsStruct');
var javaStruct=require('./javaStruct');

function getMessageObject(struct,isRoot=true){
    var content={};
    for(var message of struct.messages){
        var result=getMessageObject(message,false);
        content[result.name]=result.content;
    }
    for(var filed of struct.fileds){
        content[filed.type+" "+filed.propertyType+" "+filed.propertyName]=filed.index;
    }
    return {name:struct.name,content:content}
}

function parseBool(str){
    if(str=='1') return true;
    if(str=='true') return true;
    return false;
}


function buildMessageClassByTS(struct){
    var body="";
    for(var message of struct.messages){
        body+=buildMessageClassByTS(message);
    }
    body+=tsStruct.getMessageContentHead(struct.name.replace(/\n/g,"").replace(/\r/g,""));
    body+=tsStruct.getMessageContent(struct.fileds);
    return body+tsStruct.getMessageContentEnd();
}

function buildMessageClassByJS(struct){
    var body="";
    for(var message of struct.messages){
        body+=buildMessageClassByJS(message);
    }
    body+=jsStruct.getMessageContentHead(struct.name.replace(/\n/g,"").replace(/\r/g,""));
    body+=jsStruct.getMessageContent(struct.name,struct.fileds);
    return body+jsStruct.getMessageContentEnd(struct.name.replace(/\n/g,"").replace(/\r/g,""));
}

function buildMessageMapByTS(hash){
    var body="";
    body+=tsStruct.getMapContentHead();
    for(var name in hash){
        body+=tsStruct.getMapContent(name,hash[name]);
    }
    return body+tsStruct.getMapContentEnd();
}

function buildMessageMapByJS(hash){
    var body="";
    body+=jsStruct.getMapContentHead();
    body+=jsStruct.getMapContent(hash);
    return body+jsStruct.getMapContentEnd();
}

function buildJava(struct, output)
{
    for(var message of struct.messages){
        buildJava(message, output);
    }
    var body="";
    body+=javaStruct.getHead();
    body+=javaStruct.getContentHead(struct.name.replace(/\n/g,"").replace(/\r/g,""));
    body+=javaStruct.getContent(struct.name,struct.fileds);
    body+=javaStruct.getContentEnd(struct.name.replace(/\n/g,"").replace(/\r/g,""));

    output.push({name:struct.name,content:body});
}

function buildServerMessageMap(hash)
{
	var body="";
	body += 'package  sophia.mmorpg.proto;\n\n';
	body += 'import sophia.foundation.communication.core.MessageFactory;\n\n';
	body += 'public final class ProtoEventManager {\n\n';
	
	//生成定义
	for(var key in hash){
        body += '	public static final short '+key+' = '+hash[key]+';\n';
    }
	body += '\n';
	
	//生成注册函数
	body += '	public static final void registerActionEvents() {\n';
	for(var key in hash){
        body += '		MessageFactory.addMessage('+key+', '+key+'.class);\n';
    }
	body += '	}\n';
	
	//class end
	body += '}\n';
	
	return body;
}

module.exports=function(contents){
    //struct:{name:"",fileds:[],messages:[],opend:false};
    //filed:{type:front[0],propertyType:front[1],propertyName:front[2],index:index,default:defaultValue};
    var err1=false;
    var protosConfig={};
    var ts=tsStruct.getHead();
    var js=jsStruct.getHead();

    var javaFiles=[];
    for(var object of contents){
        for(var struct of object.structs){
            var result=getMessageObject(struct);
            var name=object.filename+"$"+result.name;

            if(protosConfig[name]){err1=result.name;break;}

            protosConfig[name]=result.content;
            ts+=buildMessageClassByTS(struct);
            //js+=buildMessageClassByJS(struct);

            buildJava(struct, javaFiles);
            //javaFiles.push({name:struct.name,content:buildJava(struct)});
        }
        if(err1) break;
    }
    var messageMap=require('./msgMap');
    var clientMap={};
    var serverMap={};
    var resultConfig={};
    for(var structName in protosConfig){
        var classname="";
        var messagename=structName;
        var keyName=structName;
        if(structName.indexOf('$')>=1){
            classname=structName.substring(0,structName.indexOf('$'));
            messagename=structName.substring(structName.indexOf('$')+1,structName.length);
        }
        var messageId=messageMap.getMesssageId(classname,messagename);
        
		serverMap[messagename]=messageId;
        clientMap[messagename]=messageId;
        resultConfig[messagename]=protosConfig[structName];
    }
    messageMap.save();

    ts+=buildMessageMapByTS(clientMap);
    js+=buildMessageMapByJS(clientMap);
	
	var svrmsgmap = buildServerMessageMap(serverMap);
	javaFiles.push({name:'ProtoEventManager',content:svrmsgmap});

    ts+=tsStruct.getEnd();
    js+=jsStruct.getEnd();
    if(err1){
        console.error('出现同名的结构体!',err1);
    }
    return {config:resultConfig,ts:ts,js:js,javaFiles:javaFiles,clientMap:clientMap,serverMap:serverMap};
}